package initialization

import UtilFuncs
import database.DataMaster
import database.IotDbFactory
import database.IotDbProperty
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*
import meta.info.*
import meta.entity.*
import meta.businessLogic.*
import org.apache.iotdb.session.template.MeasurementNode
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding
import java.sql.DriverManager
import java.util.*


val SyunityJson = Json {
    ignoreUnknownKeys = true
}

/**
 @2023-10-28 zh
 Setup.kt 以海南电校为应用场景，解决系统初始化问题。 主要包括几个方面：
 1、检查所需配置文件是否完整，不完整，则不部署
 2、检查所在硬件环境如 磁盘空间是否满足要求
 3、检查所需数据库环境是否通常（option）
 4、初始化日志文件（option）
 5、初始化配置文件（option）
 6、初始化数据库及数据（option）
 7、默认启动进程
 **/

object Setup {

    fun initDataBase() {
        /**
         *  初始化3个数据库。 其中：
         *      1、Sqlite 存储关系型数据
         *      2、MongoDB 存储非关系型数据
         *      3、IotDb 存储时间序列数据
         *      4、Oracle (option) 云端
         *      下面两个数据库用于Python算法
         *      上面第一个数据库用于业务流程，云端可以考虑oracle等大型数据库
         **/
//        createSqlite()
//        createMongodb()
        createIotDb()
    }

    fun createSqlite() {
        Class.forName("org.sqlite.JDBC")
        val conn = DriverManager.getConnection("jdbc:sqlite:src/main/resources/core.db")
        val state = conn.createStatement()
        state.executeUpdate("create table IF NOT EXISTS test(id int, name varchar(20));")
        state.executeUpdate("insert into test values (3, 'Wiki3');")
        state.executeUpdate("insert into test values (4, 'Wiki4');")
        val rs = state.executeQuery("select * from test")
        while (rs.next()){
            println("id = " + rs.getString("id") + "")
            println("name = " + rs.getString("name") + "")
        }
        rs.close()
        conn.close()
    }

    fun createMongodb() {

    }

    fun createIotDb() {
        val cloudEdgeString = UtilFuncs.readFile("src/main/resources/hn_logic.json")
        val cloudEdgeEntity = SyunityJson.decodeFromString<CloudEdge>(cloudEdgeString)

        val dp = IotDbProperty("iotdb","本地 iotdb 数据库", "127.0.0.1", 6667, "root", "root")
        val iotdb = DataMaster.instance(dp) as IotDbFactory //后面用抽象方法
        /** -----------------------   启动Iotdb 为每一个网关创建数据库   ----------------------------**/
        cloudEdgeEntity.children.forEach {
            val beeId = it.edgeIns.id
            val database = "root.D${beeId}"
            iotdb.createDataBase(database)
        }

        /** -----------------------   创建元数据模板 并挂载的每一个数据库上   ----------------------------**/
        val templateSet = listOf("metertp", "meter", "socket") //创建3个元数据模板
        val meterTemplateTP = templateSet[0] //单相电表
        val meterTemplateTPList = mutableListOf("UA", "UB", "UC", "IA", "IB", "IC", "PA", "PB", "PC", "Q", "f", "PF", "EnergyA", "EnergyB", "EnergyC", "Energy")
        val meterMeasurementTPList = meterTemplateTPList.map { n ->
            MeasurementNode(n, TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY)
        }
        iotdb.createTemplate(meterTemplateTP, meterMeasurementTPList)

        val meterTemplate = templateSet[1] //单相电表
        val meterTemplateList = mutableListOf("U", "I", "P", "Q", "f", "PF", "Energy")
        val meterMeasurementList = meterTemplateList.map { n ->
            MeasurementNode(n, TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY)
        }
        iotdb.createTemplate(meterTemplate, meterMeasurementList)

        val socketTemplate = templateSet[2]
        val socketList = mutableListOf("U", "I", "P", "Energy")
        val socketMeasurementList = socketList.map { n ->
            MeasurementNode(n, TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY)
        }
        iotdb.createTemplate(socketTemplate, socketMeasurementList)

        cloudEdgeEntity.children.forEach { //设置元数据模板
            val beeId = it.edgeIns.id
            val meterPath = "root.D${beeId}.Trm_at"
            val socketPath = "root.D${beeId}.Sck_20"
            iotdb.setTemplate(meterTemplate, meterPath)
            iotdb.setTemplate(socketTemplate, socketPath)
        }

        cloudEdgeEntity.children.forEach { edge -> //创建时间序列
            val beeId = edge.edgeIns.id
            val meters = edge.meters
            val sockets = edge.sockets
            meters.forEach { mit ->
                if(mit.id.indexOf("virtual3") == -1){
                    println("create timeseries using schema template on root.D${beeId}.Trm_at.${mit.id.replace("-","_")}")
                    iotdb.commandRawSql("create timeseries using schema template on root.D${beeId}.Trm_at.${mit.id.replace("-","_")}")
                }
            }
            sockets.forEach { sit ->
                println("create timeseries using schema template on root.D${beeId}.Sck_20.${sit.id.replace("-","_")}")
                iotdb.commandRawSql("create timeseries using schema template on root.D${beeId}.Sck_20.${sit.id.replace("-","_")}")
            }
        }

        /** -----------------------   单独创建总表 并创建一条测试数据   ----------------------------**/
        val path = "root.D86570000029.Trm_dt.Trm_virtual3_00032"
        val measurements = mutableListOf("UA", "UB", "UC", "U", "IA", "IB", "IC", "I", "PA", "PB", "PC", "P", "Q", "f", "PF",
            "EnergyA", "EnergyB", "EnergyC", "Energy")
        val types = mutableListOf<TSDataType>()
        val valueList = mutableListOf<Any>()
        for (i in 0..19) {
            types.add(TSDataType.FLOAT)
            valueList.add(Random().nextFloat())
        }
        iotdb.insertRecord(path, 1640966399000, measurements, types, valueList)
    }

    fun initResource(){ //这块工作不能省，是未来自动计算、生成可视化图的基础
        createPhysicals()
        createInfoSystem()
        createLogicSystem()
    }

    fun createPhysicals() {
        /** ----------------------  创建站点（根节点）--------------------------**/
        val station = Station(
            "HAINAN-UNIVERISTY-${UtilFuncs.counterFormat(5, "0")}",
            "海南电校",
            "Enterprise-${UtilFuncs.unique(16)[0]}",
            "root",
            mutableListOf(),
            "-1")
        station.voltageLevel = "10kV"
        station.industryCategory = "第三产业"
        station.industryType = "居民生活用电"
        station.area = 95131.0F
        station.population = 10000
        station.legalPerson = "徐慧琳"
        station.contact = "0898-65317710"
        station.dutyParagraph = "91460100MA5T2MGD14"
        station.memo = ""

        /** ----------------------  创建高压进线、变压器、低压出线（根节点）--------------------------**/
        val inSwitch = InlineSwitch(
            "INLINE-SWITCH-${UtilFuncs.counterFormat(5, "1")}",
            "进线开关(计量点)",
            "InSwitch-${UtilFuncs.unique(16)[0]}",
            station.id,
            mutableListOf(),
            station.getRoute()
        )
        inSwitch.inVol = "10kV"
        inSwitch.outVol = "0.4kV"
        inSwitch.switchType = "3元件计量"
        inSwitch.memo = ""
        station.children.add(inSwitch)

        val transformer = Transformer(
            "TRANSFORMER-SCB-${UtilFuncs.counterFormat(5, "1")}",
            "800kVA厢式变压器",
            "Transformer-${UtilFuncs.unique(16)[0]}",
            station.id,
            mutableListOf(),
            station.getRoute()
        )
        transformer.currentRatio = ""
        transformer.voltageRatio = ""
        transformer.memo = ""
        station.children.add(transformer)

        listOf("备用1", "备用2", "水泵房(可中断)", "污水站", "备用3", "知味园",
            "创新楼(总出线)", "路灯", "联络开关").map {
            val outlineSwitch = OutlineSwitch(
                "OUTLINE-SWITCH-${UtilFuncs.counterFormat(5, "1")}",
                it,
                "Switch-Load-${UtilFuncs.unique(16)[0]}",
                station.id,
                mutableListOf(),
                station.getRoute()
            )
            station.children.add(outlineSwitch)
        }

        /** ----------------------  添加充电桩（备用3）--------------------------**/
        listOf("60kW快充桩1", "60kW快充桩2", "7kW快充桩1", "7kW快充桩2", "7kW快充桩3", "7kW快充桩4").map {
            val pile = ChargingPile(
                "CHARGINGPILE-FAST-${UtilFuncs.counterFormat(5, "2")}",
                "60kW快充桩1",
                "Charging-${UtilFuncs.unique(16)[0]}",
                station.id,
                mutableListOf(),
                station.getRoute()
            )
            pile.capacity = if(it.startsWith("60")) 60.0F else 7.0F

        }

        /** ----------------------  添加联络开关（备用3）--------------------------**/
        val innovationNode = station.findChild("创新楼(总出线)")
        val backup3 = station.findChild("备用3")
        val ats1 = ContactSwitch(
            "CONTACTOR-Load-${UtilFuncs.counterFormat(5, "2")}",
            "创新楼联络开关",
            "ContactSwitch1-${UtilFuncs.unique(16)[0]}",
            innovationNode!!.id,
            mutableListOf(),
            innovationNode.getRoute(),
        )
        ats1.state = "normal"
        val ats2 = ContactSwitch(
            "CONTACTOR-Load-${UtilFuncs.counterFormat(5, "2")}",
            "区域2联络开关",
            "ContactSwitch2-${UtilFuncs.unique(16)[0]}",
            backup3!!.id,
            mutableListOf(),
            backup3.getRoute(),
        )
        ats2.state = "normal"
        innovationNode.children.add(ats1)
        backup3.children.add(ats2)

        /** ----------------------  添加柴油发电机、微网离并开关（联络开关）--------------------------**/
        val diesel1 = Diesel(
            "DIESEL-EMERGENCY-${UtilFuncs.counterFormat(5, "3")}",
            "柴油发电机1",
            "Diesel-${UtilFuncs.unique(16)[0]}",
            ats1.id,
            mutableListOf(),
            ats1.getRoute(),
        )
        diesel1.capacity = 220F
        val microGridSwitch1 = OutlineSwitch(
            "MICROGRID-SWITCH-${UtilFuncs.counterFormat(5, "3")}",
            "微网1离并网切换开关",
            "Microgrid1-${UtilFuncs.unique(16)[0]}",
            ats1.id,
            mutableListOf(),
            ats1.getRoute()
        )
        ats1.children.add(diesel1)
        ats1.children.add(microGridSwitch1)
        val diesel2 = Diesel(
            "DIESEL-EMERGENCY-${UtilFuncs.counterFormat(5, "3")}",
            "柴油发电机2",
            "Diesel-${UtilFuncs.unique(16)[0]}",
            ats2.id,
            mutableListOf(),
            ats2.getRoute(),
        )
        diesel2.capacity = 350F
        val microGridSwitch2 = OutlineSwitch(
            "MICROGRID-SWITCH-${UtilFuncs.counterFormat(5, "3")}",
            "微网2离并网切换开关",
            "Microgrid2-${UtilFuncs.unique(16)[0]}",
            ats2.id,
            mutableListOf(),
            ats2.getRoute()
        )
        ats2.children.add(diesel2)
        ats2.children.add(microGridSwitch2)

        /** ----------------------  添加光伏、储能、分路开关（微网一）--------------------------**/
        val grid1PV1 = Photovoltaic(
            "PV-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "创新楼光伏",
            "InnovationPV-${UtilFuncs.unique(16)[0]}",
            microGridSwitch1.id,
            mutableListOf(),
            microGridSwitch1.getRoute(),
        )
        grid1PV1.capacity = 26.24F
        val grid1PV2 = Photovoltaic(
            "PV-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "厚德阁光伏",
            "HoudePV-${UtilFuncs.unique(16)[0]}",
            microGridSwitch1.id,
            mutableListOf(),
            microGridSwitch1.getRoute(),
        )
        grid1PV2.capacity = 22.14F
        val grid1Battery = BatteryStation(
            "BATTERY-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "电池储能1",
            "Battery1-${UtilFuncs.unique(16)[0]}",
            microGridSwitch1.id,
            mutableListOf(),
            microGridSwitch1.getRoute(),
        )
        grid1Battery.maxPower = 100F
        grid1Battery.capacity = 100F
        val grid1Switch = OutlineSwitch(
            "OUTLINE-SWITCH-${UtilFuncs.counterFormat(5, "4")}",
            "微网1分路开关",
            "BuildingGroup1-${UtilFuncs.unique(16)[0]}",
            microGridSwitch1.id,
            mutableListOf(),
            microGridSwitch1.getRoute()
        )
        microGridSwitch1.children.add(grid1PV1)
        microGridSwitch1.children.add(grid1PV2)
        microGridSwitch1.children.add(grid1Battery)
        microGridSwitch1.children.add(grid1Switch)


        /** ----------------------  添加光伏、储能、分路开关（微网二）--------------------------**/
        val grid2PV1 = Photovoltaic(
            "PV-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "绿色楼光伏",
            "GreenPV-${UtilFuncs.unique(16)[0]}",
            microGridSwitch2.id,
            mutableListOf(),
            microGridSwitch2.getRoute(),
        )
        grid2PV1.capacity = 26.24F
        val grid2PV2 = Photovoltaic(
            "PV-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "知味园光伏",
            "ZhiweiPV-${UtilFuncs.unique(16)[0]}",
            microGridSwitch2.id,
            mutableListOf(),
            microGridSwitch2.getRoute(),
        )
        grid2PV1.capacity = 45.92F
        val grid2Battery = BatteryStation(
            "BATTERY-LOW-${UtilFuncs.counterFormat(5, "4")}",
            "电池储能2",
            "Battery2-${UtilFuncs.unique(16)[0]}",
            microGridSwitch2.id,
            mutableListOf(),
            microGridSwitch2.getRoute(),
        )
        grid2Battery.maxPower = 200F
        grid2Battery.capacity = 200F
        val grid2Switch = OutlineSwitch(
            "OUTLINE-SWITCH-${UtilFuncs.counterFormat(5, "4")}",
            "微网2分路开关",
            "BuildingGroup2-${UtilFuncs.unique(16)[0]}",
            microGridSwitch2.id,
            mutableListOf(),
            microGridSwitch2.getRoute()
        )
        microGridSwitch2.children.add(grid2PV1)
        microGridSwitch2.children.add(grid2PV2)
        microGridSwitch2.children.add(grid2Battery)
        microGridSwitch2.children.add(grid2Switch)

        /** ----------------------  添加微网一建筑群（微网一）--------------------------**/
        listOf("创新楼", "厚德阁").map {
            val building1 = BuildingLoad(
                "BUILDING-LOW-${UtilFuncs.counterFormat(5, "5")}",
                it,
                "Building-Load-${UtilFuncs.unique(16)[0]}",
                grid1Switch.id,
                mutableListOf(),
                grid1Switch.getRoute()
            )
            grid1Switch.children.add(building1)
        }

        /** ----------------------  添加微网二建筑群（微网二）--------------------------**/
        listOf("知味园厨房(重要)", "水泵房", "问道阁", "绿色楼", "信息中心", "开放楼").map {
            val building2 = BuildingLoad(
                "BUILDING-LOW-${UtilFuncs.counterFormat(5, "5")}",
                it,
                "Building-Load-${UtilFuncs.unique(16)[0]}",
                grid2Switch.id,
                mutableListOf(),
                grid2Switch.getRoute()
            )
            grid2Switch.children.add(building2)
        }


        /** ----------------------  添加知味园厨房餐厅（低压分路开关）--------------------------**/
        val zwSwitchEntity = station.findChild("知味园")!!
        val zwBuilding = BuildingLoad(
            "BUILDING-LOW-${UtilFuncs.counterFormat(5, "5")}",
            "知味园餐厅",
            "Building-Load-${UtilFuncs.unique(16)[0]}",
            zwSwitchEntity.id,
            mutableListOf(),
            zwSwitchEntity.getRoute()
        )
        repeat(2){ floorIndex ->
            val floor = FloorLoad(
                "FLOOR-LOW-${UtilFuncs.counterFormat(5, "6")}",
                "知味园餐厅${floorIndex + 1}楼",
                "CantingFloor${floorIndex + 1}-${UtilFuncs.unique(16)[0]}",
                zwBuilding.id,
                mutableListOf(),
                zwBuilding.getRoute()
            )
            listOf("101", "102", "201", "202", "203", "204", "205").forEach { room_number ->
                val roomFloor = room_number.substring(0, 1).toInt()
                if (roomFloor == (floorIndex + 1)){
                    val room = RoomLoad(
                        "ROOM-LOW-${UtilFuncs.counterFormat(5, "7")}",
                        "知味园${floorIndex + 1}楼${room_number}房间",
                        "CantingFloor${floorIndex + 1}Room${room_number}-${UtilFuncs.unique(16)[0]}",
                        floor.id,
                        mutableListOf(),
                        floor.getRoute()
                    )
                    listOf("立式空调1","立式空调2","立式空调3").forEachIndexed{ index, name ->
                        val appliance = Appliance(
                            "APPLIANCE-LOW-${UtilFuncs.counterFormat(5, "8")}",
                            "知味园${floorIndex + 1}楼${room_number}房间${name}",
                            "CantingFloor${floorIndex + 1}Room${room_number}Appliance${index + 1}-${UtilFuncs.unique(16)[0]}",
                            room.id,
                            mutableListOf(),
                            room.getRoute()
                        )
                        room.children.add(appliance)
                    }
                    floor.children.add(room)
                }
            }
            zwBuilding.children.add(floor)
        }
        zwSwitchEntity.children.add(zwBuilding)

        /** ----------------------  添加建筑负荷（全部）--------------------------**/
        // 缺少水泵房和信息中心，从list改为data class
        listOf(
            BuildingInitEntity("厚德阁",true,5,"微网1分路开关","Houde",
                roomNumberList = listOf(27, 27, 27, 27, 27),
                applianceList = listOf("热水壶","电视","空调","电脑","手机","用电设备1","用电设备2","用电设备3")),
            BuildingInitEntity("创新楼",false,5,"微网1分路开关","Innovation",
                roomStringList = listOf("101", "102", "103", "201", "202", "203", "301", "302", "401", "402", "501"),
                applianceList = listOf("立式空调1","立式空调2","立式空调3","立式空调4","立式空调5")),
            BuildingInitEntity("知味园厨房(重要)",false,1,"微网2分路开关","ZWCanting",
                roomStringList = listOf("101"),
                applianceList = listOf("厨房重要负荷")),
            BuildingInitEntity("问道阁",true,3,"微网2分路开关","Wendao",
                roomNumberList = listOf(18, 17, 17),
                applianceList = listOf("热水壶","电视","空调","电脑","手机","烘干机1","烘干机2","熨斗", "洗衣机1", "洗衣机2")),
            BuildingInitEntity("绿色楼",false,5,"微网2分路开关","Green",
                roomStringList = listOf("102", "103", "104", "201", "202", "203", "301", "302", "401", "402", "403", "502", "503", "504"),
                applianceList = listOf("立式空调1","立式空调2","专业空调")),
            BuildingInitEntity("开放楼",false,5,"微网2分路开关","Open",
                roomStringList = listOf("101", "201", "301", "302", "303", "304", "305", "401", "402", "403", "404", "405", "501", "502", "503"),
                applianceList = listOf("立式空调1","立式空调2"))
        ).map { entity ->
            val switchEntity = if(entity.positionName == "微网1分路开关") grid1Switch else grid2Switch
            val buildingEntity = switchEntity.findChild(entity.name)!!

            repeat(entity.floor){ floorIndex ->
                val floor = FloorLoad(
                    "FLOOR-LOW-${UtilFuncs.counterFormat(5, "6")}",
                    "${entity.name}${floorIndex+1}楼",
                    "${entity.enCode}Floor${floorIndex+1}-${UtilFuncs.unique(16)[0]}",
                    buildingEntity.id,
                    mutableListOf(),
                    buildingEntity.getRoute()
                )
                if (entity.batchCreate) {
                    repeat(entity.roomNumberList!![floorIndex]) { roomIndex ->
                        val room_number = (floorIndex+1).toString() + String.format("%02d", roomIndex+1)
                        val room = RoomLoad(
                            "ROOM-LOW-${UtilFuncs.counterFormat(5, "7")}",
                            "${entity.name}${floorIndex+1}楼${room_number}房间",
                            "${entity.enCode}Floor${floorIndex+1}Room${room_number}-${UtilFuncs.unique(16)[0]}",
                            floor.id,
                            mutableListOf(),
                            floor.getRoute()
                        )
                        entity.applianceList.forEachIndexed{ index, name ->
                            val appliance = Appliance(
                                "APPLIANCE-LOW-${UtilFuncs.counterFormat(5, "8")}",
                                "${entity.name}${floorIndex+1}楼${room_number}房间${name}",
                                "${entity.enCode}Floor${floorIndex+1}Room${room_number}Appliance${index+1}-${UtilFuncs.unique(16)[0]}",
                                room.id,
                                mutableListOf(),
                                room.getRoute()
                            )
                            room.children.add(appliance)
                        }
                        floor.children.add(room)
                    }
                } else {
                    entity.roomStringList!!.forEach { room_number ->
                        val roomId = room_number.substring(0, 1).toInt()
                        if (roomId == (floorIndex + 1)){
                            val room = RoomLoad(
                                "ROOM-LOW-${UtilFuncs.counterFormat(5, "7")}",
                                "${entity.name}${floorIndex + 1}楼${room_number}房间",
                                "${entity.enCode}${floorIndex + 1}Room${room_number}-${UtilFuncs.unique(16)[0]}",
                                floor.id,
                                mutableListOf(),
                                floor.getRoute()
                            )
                            entity.applianceList.forEachIndexed{ index, name ->
                                val appliance = Appliance(
                                    "APPLIANCE-LOW-${UtilFuncs.counterFormat(5, "8")}",
                                    "${entity.name}${floorIndex + 1}楼${room_number}房间${name}",
                                    "${entity.enCode}Floor${floorIndex + 1}Room${room_number}Appliance${index + 1}-${UtilFuncs.unique(16)[0]}",
                                    room.id,
                                    mutableListOf(),
                                    room.getRoute()
                                )
                                room.children.add(appliance)
                            }
                            floor.children.add(room)
                        }
                    }
                }
                buildingEntity.children.add(floor)
            }
        }
        UtilFuncs.saveMetaFile3(station, "src/main/resources/hn_origin.json")

    }

    fun createInfoSystem() {
        val stationString = UtilFuncs.readFile("src/main/resources/hn_origin.json")
        val newStation = SyunityJson.decodeFromString<Station>(stationString)
        newStation.printTree()

        /** ----------------------  添加云计算中心（云）--------------------------**/
        val cloudComputing =CloudComputing(
            "CLOUD-HUADONG-${UtilFuncs.counterFormat(5, "0")}",
            "海南电网云计算中心"
        ).apply {
            this.ip = "beepower.com.cn"
            this.port = 8080
            this.lifespan = 1767196800000
        }

        /** ----------------------  添加网络中间件（云）--------------------------**/
        val messageBroker = MessageBroker(
            "MOSQUITTO-HUADONG-${UtilFuncs.counterFormat(5, "0")}",
            "海南电校网络中间件").apply {
            this.ip = "beepower.com.cn"
            this.port = 9883
            this.lifespan = 1767196800000
            this.clientId = "9001030"
            this.username = "scn"
            this.password = "123456"
        }

        /** ----------------------  添加边缘计算节点（边）--------------------------**/
        val beginStr = "8657000"  //网关编号从8657000开始
        val recursionList = mutableListOf<MetaTree>(newStation) //初始化一定要建立在抽象上，否则后面会报错
        val edges: MutableList<MetaInfo> = mutableListOf()

        while (recursionList.size > 0){
            val curNode = recursionList[0]
            if (curNode is FloorLoad){
                val edge = EdgeComputing(
                    UtilFuncs.counterFormat(5, beginStr),
                    curNode.name + "网关").apply {
                    this.ip = ""
                    this.port = 9883
                    this.lifespan = 1767196800000
                }
                edges.add(edge)
            }
            recursionList.removeAt(0)
            curNode.children.forEach { recursionList.add(it) }
        }

        listOf("进线开关(计量点)网关", "微网1网关", "微网2网关").forEach {
            val extra = EdgeComputing(UtilFuncs.counterFormat(5, beginStr), it).apply {
                this.ip = ""
                this.port = 9883
                this.lifespan = 1767196800000
            }
            edges.add(extra)
        }

        /** ----------------------  添加智能终端（端）--------------------------**/
        //先创建电表
        val meters: MutableList<MetaInfo> = mutableListOf()
        val meterList = mutableListOf<MetaTree>(newStation)
        while (meterList.size > 0){
            val curNode = meterList[0]
            if (curNode is InlineSwitch){ //进线节点，添加3相电表
                val meter = SmartMeter(
                    "Trm-virtual3-${UtilFuncs.counterFormat(5, "0")}",
                    "${curNode.name}电表(3相)").apply {
                    this.ip = ""
                    this.port = 9883
                    this.lifespan = 1767196800000
                }
                meters.add(meter)
            }else if (curNode !is Station && curNode !is Appliance){
                val meter = SmartMeter(
                    "Trm-virtual-${UtilFuncs.counterFormat(5, "0")}",
                    "${curNode.name}电表").apply {
                    this.ip = ""
                    this.port = 9883
                    this.lifespan = 1767196800000
                }
                meters.add(meter)
            }
            meterList.removeAt(0)
            curNode.children.forEach { meterList.add(it) }
        }
        // 创建插座
        val sockets: MutableList<MetaInfo> = mutableListOf()
        val socketList = mutableListOf<MetaTree>(newStation)
        while (socketList.size > 0){
            val curNode = socketList[0]
            if (curNode is Appliance){
                val socket = SmartSocket(
                    "Sck-20-${UtilFuncs.counterFormat(5, "0")}",
                    "${curNode.name}插座").apply {
                    this.ip = ""
                    this.port = 9883
                    this.lifespan = 1767196800000
                }
                sockets.add(socket)
            }
            socketList.removeAt(0)
            curNode.children.forEach { socketList.add(it) }
        }

        /** ----------------------  通过数据类保存至文件 --------------------------**/
        val infoSystem = InfoJson(cloudComputing, messageBroker, edges, meters, sockets)
        UtilFuncs.saveMetaFile2(Json.encodeToString(infoSystem), "src/main/resources/hn_infoSystem.json")
    }

    fun createLogicSystem() {

        val infoSystemString = UtilFuncs.readFile("src/main/resources/hn_infoSystem.json")
        val newInfoJson = SyunityJson.decodeFromString<InfoJson>(infoSystemString)

        /** -----------------------   建立逻辑   ----------------------------**/
        val edges = newInfoJson.edges
        val meters = newInfoJson.meters
        val sockets = newInfoJson.sockets


        val inSwitchList = listOf("进线开关(计量点)","800kVA箱式变压器", "备用1", "备用2", "水泵房(可中断)", "污水站", "备用3", "知味园", "创新楼(总出线)", "路灯", "创新楼联络开关", "联络开关")
        val microList1 = listOf("柴油发电机1","创新楼光伏","厚德阁光伏","电池储能1","微网1分路开关","创新楼","厚德阁", "区域2联络开关")
        val microList2 = listOf("柴油发电机2", "绿色楼光伏", "知味园光伏", "电池储能2", "微网2分路开关", "知味园餐厅", "水泵房", "问道阁", "绿色楼", "信息中心", "开放楼")

        val newLogic = CloudEdge(newInfoJson.cloud, newInfoJson.broker, mutableListOf())

        edges.forEach { edge ->
            when (edge.id){
                "86570000029" -> { //箱变网关
                    val lower = EdgeTerminal(edge, newInfoJson.findMeters(inSwitchList), mutableListOf())
                    newLogic.children.add(lower)
                }
                "86570000030" -> { // 微网1网关
                    val lower = EdgeTerminal(edge, newInfoJson.findMeters(microList1), mutableListOf())
                    newLogic.children.add(lower)
                }
                "86570000031" -> { // 微网2网关
                    val lower = EdgeTerminal(edge, newInfoJson.findMeters(microList2), mutableListOf())
                    newLogic.children.add(lower)
                }
                else -> {
                    val matchName = edge.name.replace("网关","")
                    val findMeters = meters.filter { it.name.contains(matchName) }
                    val findSockets = sockets.filter { it.name.contains(matchName) }
                    val lower = EdgeTerminal(edge, findMeters, findSockets)
                    newLogic.children.add(lower)
                }
            }
        }

        /** ----------------------  通过数据类保存至文件 --------------------------**/
        UtilFuncs.saveMetaFile2(Json.encodeToString(newLogic), "src/main/resources/hn_logic.json")
    }
}


fun main(args: Array<String>) {
//    Setup.initResource()
    Setup.initDataBase()
}